package com.cjx.stars.task;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cjx.stars.pojo.table.User;
import com.cjx.stars.pojo.vo.UserVo;
import com.cjx.stars.service.UserService;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.cjx.stars.constant.RedisConstant.*;

/**
 * @author cjx
 * @description 凌晨1点缓存所有用户的推荐用户 ，缓存5页数据
 * @createDate 2024/4/24 10:47
 **/
@Component
@Log4j2
public class RecommendUserCacheTask {

    @Resource
    private UserService userService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedissonClient redissonClient;


    @Scheduled(cron = "0 0 1 * * ?")
    public void saveRecommendUserCache() {
        RLock lock = redissonClient.getLock("recommendUserCache");
        try {
            if (lock.tryLock(DEFAULT_WAIT_TIME, DEFAULT_LEASE_TIME, TimeUnit.MICROSECONDS)) {
                //1.获取所有用户
                List<User> userList = userService.list();
                //2.计算每个用户的推荐用户，计算5页数据存入Redis
                long start = System.currentTimeMillis();
                for (User user : userList) {
                    for (int i = 1; i <= 5; i++) {
                        Page<UserVo> userVoPage = userService.matchUser(i, "", user.getUserId());
                        String jsonStr = JSONUtil.toJsonStr(userVoPage);
                        String key = USER_RECOMMEND_KEY + user.getUserId() + ":" + i;
                        stringRedisTemplate.opsForValue().set(key,jsonStr,USER_RECOMMEND_TTL,TimeUnit.HOURS);
                    }
                }
                long end = System.currentTimeMillis();
                log.info("计算所有用户推荐用户耗时：{} 毫秒",end - start);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }

    }

}
